package game;

import fields.*;

import java.util.*;

import dataAccess.*;
import boundaryToMatador.GUI;

public class Player {

	// Ting, som programmet skal huske om spilleren.
	private int playerID;
	private String name;
	private PropertyManager props;
	private int field, dice, account, outOfJailCards, turnsInJail;
	private boolean lost, inJail, choice;
	MySQLPlayerDAO playerDAO;
	MySQLFieldDAO fieldDAO;

	// Konstruktoer er den der laver et objekt fx. en spiller.
	public Player() {
		playerID = 0;
		name = "";
		account = 30000;
		dice = 0;
		field = 1;
		turnsInJail = 0;
		inJail = false;
		lost = false; // Sættes til true, hvis spillerens konto går i 0.
		outOfJailCards = 0;
		props = new PropertyManager();
		choice = false;
		playerDAO = new MySQLPlayerDAO();
		fieldDAO = new MySQLFieldDAO();
	}

	public Player(int playerID, String name, int account, int dice, int field,
			int turnsInJail, boolean inJail, boolean lost, int outOfJailCards,
			PropertyManager props, boolean choice) {
		this.playerID = playerID;
		this.name = name;
		this.account = account;
		this.dice = dice;
		this.field = field;
		this.turnsInJail = turnsInJail;
		this.inJail = inJail;
		this.lost = lost;
		this.outOfJailCards = outOfJailCards;
		this.props = props;
		this.choice = choice;
		playerDAO = new MySQLPlayerDAO();
		fieldDAO = new MySQLFieldDAO();
	}
	
	public void setPlayerID(int playerID){
		this.playerID = playerID;
	}
	
	public int getPlayerID() {
		return playerID;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setInJail() {
		inJail = true;
		turnsInJail = 3;
		field = 31;	
	}

	public void addOutOfJailCard() {
		outOfJailCards++;
	}

	public void useOutOfJailCard() {
		outOfJailCards--;
		getOutOfJail();
	}

	public void getOutOfJail() {
		inJail = false;
		turnsInJail = 0;
		moveTo(11);
	}

	public int getTurnsInJail() {
		return turnsInJail;
	}

	public int outOfJailCards() {
		return outOfJailCards;
	}

	public void stayInJail() {
		turnsInJail--;
	}

	public void move(int move) {
		if (!inJail) {
			field += move;
			if (field > 40)
				field = field % 40;
			if (field < 0)
				field+=40;
		}
	}

	public void moveTo(int field) {
		if (!inJail)
			this.field = field;
	}

	public int getField() {
		return field;
	}

	public void setChoice(boolean choice) {
		this.choice = choice;
	}

	public boolean getChoice() {
		return choice;
	}

	public String getName() {
		return name;
	}

	public boolean hasLost() {
		if (account == 0)
			lost = true;
		return lost;	
	}
	
	public void DeleteFromDB() {
		if (account == 0)
			try {
				fieldDAO.deletePlayerFromField(playerID);
				playerDAO.deletePlayer(playerID);
			} catch (DALException e) {
				e.printStackTrace();
			}	
	}

	public void bankrupt() {
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Territory)
				((Territory) props.getProperty(i)).setHouses(0);
			props.getProperty(i).forSale();
			props.removeProperty(i);
		}
	}

	public int getAccount() {
		return account; // Test
	}

	public void deposit(int amount) {
		account += amount;
	}

	public void setAccount(int account) {
		this.account = account;
	}

	public void withdraw(int amount) {
		if (amount < 0)
			amount = Math.abs(amount);
		account -= amount;
		if (account < 0) {
			account = 0;
		}
	}

	public void transfer(int amount, Player p) {
		withdraw(amount);
		p.deposit(amount);
	}

	public void resetAccount() {
		account = 0;
	}

	public boolean isInJail() {
		return inJail;
	}

	public void setDice(int d) {
		dice = d;
	}

	public int getDice() {
		return dice;
	}

	public int numberOfShips() {
		int ships = 0;
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Ships)
				ships++;
		}
		return ships;
	}

	public int numberOfBreweries() {
		int brews = 0;
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Brewery)
				brews++;
		}
		return brews;
	}

	public void buyProperty(Ownable field, int price) {
		props.addProperty(field);
		withdraw(price);
	}

	// Kaldes af sælgeren i en handel.
	public void makePropertyDeal(Ownable field, Player buyer, int price) {
		props.removeProperty(props.getPropertyIndex(field.getNumber()));
		deposit(price);
		buyer.buyProperty(field, price);
		field.setOwner(buyer);
	}

	public boolean isOwner(Field field) {
		return props.containsProperty((Ownable) field);
	}

	public int calculateTotalAssets() {
		return account + props.propertyValue();
	}

	public int pawnedProperties() {
		int pawns = 0;
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i).isPawned())
				pawns++;
		}
		return pawns;
	}

	public boolean isOutOfCash() {
		return account == 0;
	}

	public int totalProperties() {
		return props.numberOfProperties();
	}

	public boolean propertiesToPawn() {
		int pawned = 0;
		if (props.numberOfProperties() == 0)
			return false;
		else {
			for (int i = 0; i < props.numberOfProperties(); i++) {
				if (props.getProperty(i).isPawned())
					pawned++;
			}
		}
		return pawned < props.numberOfProperties();
	}

	public int totalHouses() {
		return props.totalHouses();
	}

	public int numberOfProportiesAtStreet(String color) {
		return props.buildingsWithColor(color);
	}

	public boolean canBuild() {
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Territory) {
				Territory field = (Territory) props.getProperty(i);
				if (props.buildingsInGroup(field.getNumber()) == props
						.buildingsWithColor(field.getColor()))
					return true;
			}
		}
		return false;
	}
	
	public Ownable getProperty(int index) {
		return props.getProperty(index);
	}

	public boolean canBuildAtProperty(int fieldnumber, String color) {
		return props.buildingsInGroup(fieldnumber) == props
				.buildingsWithColor(color);
	}

	public boolean needToEvenlyBuild(int fieldnumber) {
		String color = ((Territory) props.getProperty(props
				.getPropertyIndex(fieldnumber))).getColor();
		int selfHouses = ((Territory) props.getProperty(props
				.getPropertyIndex(fieldnumber))).getHouses();
		Territory field;
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Territory
					&& props.getProperty(i).getNumber() != fieldnumber) {
				field = (Territory) props.getProperty(i);
				if (field.getColor().equals(color))
					if (selfHouses - field.getHouses() == 1)
						return true;
			}
		}
		return false;
	}
	
	public boolean needToEvenlyRemove(int fieldnumber) {
		String color = ((Territory) props.getProperty(props.getPropertyIndex(fieldnumber))).getColor();
		int selfHouses = ((Territory) props.getProperty(props.getPropertyIndex(fieldnumber))).getHouses();
		Territory field;
		for (int i = 0; i < props.numberOfProperties(); i++) {
			if (props.getProperty(i) instanceof Territory && props.getProperty(i).getNumber() != fieldnumber) {
				field = (Territory) props.getProperty(i);
				if (field.getColor().equals(color))
					if (field.getHouses() - selfHouses == 1)
						return true;
			}
		}
		return false;
	}

	public void addBuilding(int fieldnumber) {
		int index = props.getPropertyIndex(fieldnumber);
		if (props.getProperty(index) instanceof Territory)
			((Territory) props.getProperty(index)).addBuilding();
	}

	public void removeBuilding(int fieldnumber) {
		int index = props.getPropertyIndex(fieldnumber);
		if (props.getProperty(index) instanceof Territory)
			((Territory) props.getProperty(index)).removeBuilding();
	}
}